
'''	
	This file is part of Roseena.
	
	Copyright (C) 2008	Mohamed Hazem <mohamed.hazem@student.guc.edu.eg>
	Copyright (C) 2008	Mostafa Hany <mostafa.hany@student.guc.edu.eg>

	
	Roseena is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	Roseena is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with Roseena.	If not, see <http://www.gnu.org/licenses/>.
'''

from PyQt4.QtCore import SIGNAL, QDataStream, QByteArray, QIODevice, QObject
from PyQt4.QtNetwork import QTcpSocket

SIZEOF_UINT16 = 2

class Client(QObject):
	'''
	The Client class responsible for sending requests to the server
	and handle incoming responses.
	'''
	def __init__(self, host, port):
		'''
		The Client's __init__ method; takes two arguments: QString host and int port ... where
		host is the server's hostname.
		'''
		self.host = host
		self.port = port

		self.socket = QTcpSocket()
		self.nextBlockSize = 0
		self.request = None

		self.connect(self.socket, SIGNAL("connected()"), self.sendRequest)
		self.connect(self.socket, SIGNAL("readyReady()"), self.readResponse)

	def issueRequest(self, requestString):
		'''
		Method responsible for issuing requests.

		Example: issueRequest("GET index.html HTTP/1.0")
		'''
		self.request = QByteArray()
		stream = QDataStream(self.request, QIODevice.ReadWrite)
		stream.writeUInt16(0)
		stream << requestString
		stream.device().seek(0)
		stream.writeUInt16(self.request.size() - SIZEOF_UINT16)

		if self.socket.isOpen():
			self.socket.close()

		self.socket.connectToHost(self.host, self.port)

	def sendRequest(self):
		'''
		Method responsible for sending the request after the
		connected() signal is emitted.
		'''
		self.nextBlockSize = 0
		self.socket.write(self.request)
		self.request = None

	def readResponse(self):
		stream = QDataStream(self.socket)
		stream.setVersion(QDataStream.Qt_4_4)

		while True:
			if self.nextBlockSize == 0:
				if self.socket.bytesAvailable() < SIZEOF_UINT16:
					break
				self.nextBlockSize = stream.readUInt16()

			if self.socket.bytesAvailable() < self.nextBlockSize:
				break

			response = QString()
			stream >> response
			self.nextBlockSize = 0
			print "the response is " + response
